/*
 * TileSet.cpp
 *
 *  Created on: Aug 26, 2011
 *      Author: mengwei.chua
 */

#include "TileSet.h"
#include "ParserHelper.h"

namespace projectcos
{
namespace tile
{
namespace parser
{

TileSet::TileSet()
: m_FirstGID(0)
, m_Source("")
, m_Name("")
, m_TileWidth(0)
, m_TileHeight(0)
, m_Spacing(0)
, m_Margin(0)
{
	m_ImageList.clear();
	m_TileList.clear();
}

TileSet::~TileSet()
{
	m_ImageList.clear();
	m_TileList.clear();
}

bool TileSet::Parse(const TiXmlElement* element)
{
	if(NULL != element)
	{
		TIXML_QUERY_UNSIGNED_INT(element, "firstgid", m_FirstGID);
		TIXML_QUERY_STRING(element, "source", m_Source);
		TIXML_QUERY_STRING(element, "name", m_Name);
		TIXML_QUERY_UNSIGNED_INT(element, "tilewidth", m_TileWidth);
		TIXML_QUERY_UNSIGNED_INT(element, "tileheight", m_TileHeight);
		TIXML_QUERY_UNSIGNED_INT(element, "spacing", m_Spacing);
		TIXML_QUERY_UNSIGNED_INT(element, "margin", m_Margin);

		const TiXmlElement* child = element->FirstChildElement("image");
		while(NULL != child)
		{
			Image image;
			if(image.Parse(child))
			{
				m_ImageList.push_back(image);
			}

			child = child->NextSiblingElement("image");
		}

		child = element->FirstChildElement("tile");
		while(NULL != child)
		{
			Tile tile;
			if(tile.Parse(child))
			{
				m_TileList.push_back(tile);
			}

			child = child->NextSiblingElement("tile");
		}


		if(!m_Source.empty())
		{
			TiXmlDocument doc;
			std::string fileName = std::string("asset/") + m_Source;

			if(!doc.LoadFile(fileName.c_str()))
			{
				return false;
			}

			child = doc.FirstChildElement("tileset");

			TIXML_QUERY_STRING(child, "name", m_Name);
			TIXML_QUERY_UNSIGNED_INT(child, "tilewidth", m_TileWidth);
			TIXML_QUERY_UNSIGNED_INT(child, "tileheight", m_TileHeight);
			TIXML_QUERY_UNSIGNED_INT(child, "spacing", m_Spacing);
			TIXML_QUERY_UNSIGNED_INT(child, "margin", m_Margin);

			child = child->FirstChildElement("image");
			while(NULL != child)
			{
				Image image;
				if(image.Parse(child))
				{
					m_ImageList.push_back(image);
				}

				child = child->NextSiblingElement("image");
			}

			child = child->FirstChildElement("tile");
			while(NULL != child)
			{
				Tile tile;
				if(tile.Parse(child))
				{
					m_TileList.push_back(tile);
				}

				child = child->NextSiblingElement("tile");
			}
		}
	}

	return true;
}

unsigned int TileSet::GetFirstGID() const
{
	return m_FirstGID;
}

std::string TileSet::GetSource() const
{
	return m_Source;
}

std::string TileSet::GetName() const
{
	return m_Name;
}

unsigned int TileSet::GetTileWidth() const
{
	return m_TileWidth;
}

unsigned int TileSet::GetTileHeight() const
{
	return m_TileHeight;
}

unsigned int TileSet::GetSpacing() const
{
	return m_Spacing;
}

unsigned int TileSet::GetMargin() const
{
	return m_Margin;
}

void TileSet::GetImages(std::deque<Image>& images) const
{
	images = m_ImageList;
}

void TileSet::GetTiles(std::deque<Tile>& tiles) const
{
	tiles = m_TileList;
}


TileSet::Tile::Tile()
: m_ID(0)
{
	m_ImageList.clear();
}

TileSet::Tile::~Tile()
{
	m_ImageList.clear();
}

bool TileSet::Tile::Parse(const TiXmlElement* element)
{
	if(NULL != element)
	{
		element->QueryUnsignedAttribute("id", &m_ID);

		const TiXmlElement* child = element->FirstChildElement("properties");
		if(NULL != child)
		{
			m_Properties.Parse(child);
		}

		child = element->FirstChildElement("image");
		while(NULL != child)
		{
			Image image;
			if(image.Parse(child))
			{
				m_ImageList.push_back(image);
			}

			child = child->NextSiblingElement("image");
		}
	}

	return true;
}

void TileSet::Tile::GetProperties(Properties& properties) const
{
	properties = m_Properties;
}

void TileSet::Tile::GetImages(std::deque<Image>& images) const
{
	images = m_ImageList;
}

} // parser
} // tile
} // projectcos
